<?php
declare(strict_types=1);

namespace app\common\model\delivery;

use app\common\model\base\BaseModel;
use app\common\model\base\ConstTraits;

class CouponList extends BaseModel
{
    use ConstTraits;

    const VERIFY_ORDER_TYPE=[
        'gasoline'=>'加油订单'
    ];

    private static $words=[
        '0','1','2','3','4','5','6','7','8','9',
        'a','b','c','d','e','f','g','h','i','j',
        'k','l','m','n','o','p','q','r','s','t',
        'u','v','w','x','y','z'
    ];

    public function coupon()
    {
        return $this->hasOne(Coupon::class,'id','coupon_id');
    }

    public function customer()
    {
        return $this->hasOne(Customer::class,'id','customer_id');
    }

    public static function checkGoods($coupon,$xgoods_id)
    {
        if(!$coupon['coupon']){
            return false;
        }
        $goods_id=$coupon['coupon']['goods_id'];
        if(!$goods_id){
            return false;
        }
        $goods_arr=explode(',',$goods_id);
        if(!in_array($xgoods_id,$goods_arr)){
            return false;
        }
        return true;
    }

    public static function send($customer_id,$coupon,$number=1,$remark='')
    {
        if($coupon->total && $coupon->total<=$coupon->send){
            throw new \Exception('商品库存不足！');
        }
        $codes=self::getCode($number);
        foreach ($codes as $code){
            $list=new self();
            $list->channel_id=$coupon->channel_id;
            $list->customer_id=$customer_id;
            $list->coupon_id=$coupon->id;
            $list->code=$code;
            if($coupon->expire){
                $list->expire_time=time()+$coupon->expire*24*3600;
            }else{
                $list->expire_time=strtotime('2099-01-01 00:00:00');
            }
            if($coupon['type']==Coupon::COUPONTYPE('商品券')){
                $list->total=$coupon->goods_number;
            }else{
                $list->total=1;
            }
            $list->take=0;
            $list->save();
            if($coupon['type']==Coupon::COUPONTYPE('充值卡')){
                CardLog::addLog($list->id,'last',$coupon->balance,'',$remark);
            }
        }
        $coupon->send+=$number;
        $coupon->save();
    }

    public static function getCode($total)
    {
        //上锁
        $et=10;
        $getlock=false;
        while ($et>0){
            if(!file_exists(root_path().'runtime/code.lock')){
                file_put_contents(root_path().'runtime/code.lock','1');
                $getlock=true;
                break;
            }
            $et--;
            sleep(1);
        }
        if(!$getlock){
            throw new \Exception('操作人数过多，请稍后重试！');
        }
        $words=[];
        $first='10000';
        $list=(new self())->withTrashed()->limit(1)->order('id desc')->select();
        if(count($list)>0){
            $first=$list[0]['code'];
        }
        for($i=0;$i<$total;$i++){
            $first=self::plus($first,4);
            $words[]=$first;
        }
        unlink(root_path().'runtime/code.lock');
        return $words;
    }

    private static function plus($last,$number)
    {
        $index=0;
        foreach (self::$words as $k=>$v){
            if($v==$last[$number]){
                $index=$k;
            }
        }
        if(isset(self::$words[$index+1])){
            $next=self::$words[$index+1];
            $r='';
            for($i=0;$i<$number;$i++){
                $r.=$last[$i];
            }
            $r=$r.$next;
            $pd=4-$number;
            for($i=0;$i<$pd;$i++){
                $r.='0';
            }
            return $r;
        }else{
            $number--;
            return self::plus($last,$number);
        }
    }
}